#ifndef _MYEXCEPTION_H_
#define _MYEXCEPTION_H_

#include <sys/types.h>
#include <cstdio>
#include <exception>

namespace flexse
{
	class MyException : public std::exception
	{
		private:
			static const u_int32_t MaxStringSize = 256;
			static const u_int32_t StringSafePostfix = 4;

		private:
			static const char * const PrintPattern;

			//information
			u_int32_t m_line;
			//append some zeroes at end to prevent the hale Chinese character thing
			char m_filename[MaxStringSize + StringSafePostfix];
			char m_message[MaxStringSize + StringSafePostfix];
			char m_method[MaxStringSize + StringSafePostfix];

		private:
			static void * operator new(size_t);
			MyException();

		public:
			MyException(const char * message, const char * filename, u_int32_t line, const char * method);
			//As there are no handler menbers, it would be save to use the one generated by compiler by default
			//MyException(const MyException &);

            const char * Message(void) const;
            const char * FileName(void) const;
            u_int32_t Line(void) const;
            const char * Method(void) const;

            ssize_t PrintMessage(FILE * stream) const;
    };


#define MyToolThrow(message) \
    do \
    { \
        throw flexse::MyException(message, __FILE__, __LINE__, __func__); \
    } \
    while(false)

#define MyThrowAssert(expression) \
    do \
    { \
        if(expression) \
        { \
        } \
        else \
        { \
            FATAL ("MyThrowAssert Failed. ["#expression"]");\
            throw flexse::MyException("MyThrowAssert Failed. ["#expression"]", __FILE__, __LINE__, __func__); \
        } \
    } \
    while(false)

#define MySuicideAssert(expression) \
    do \
    { \
        if(expression) \
        { \
        } \
        else \
        { \
            FATAL("MySuicideAssert Failed. ["#expression"]"); \
            while(0 != raise(SIGKILL)){} \
            exit(1); \
        } \
    } \
    while(false)

}


#endif


